import { trigger, track, effect } from './reactive-computed.js'

function watch (source, cb, options) {
  let getter
  if (typeof source === 'function') {
    getter = source
  } else {
    getter = () => traverse(source)
  }

  let newValue, oldValue
  let cleanup
  function onValidate (fn) {
    cleanup = fn
  }
  const job = () => {
    newValue = effectFn()
    if (cleanup) {
      cleanup()
    }
    cb(newValue, oldValue, onValidate)
    oldValue = newValue
  }

  effect(() => traverse(source), {
    lazy: true,

    scheduler () {
      if (options.flush == 'post') {
        Promise.resolve().then(() => {
          job()
        })
      } else {
        job()
      }
    }
  })

  if (options.immidiate) {
    job()
  } else {
    oldValue = effectFn()
  }
}

function traverse (value, seen = new Set()) {
  if (typeof value !== 'object' || value === null || seen.has(value)) return
  seen.add(value)
  for (const k in value) {
    traverse(value[k], seen)
  }
  return value
}
